/**
适配器模式（Adapter Pattern）

意图：将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
主要解决：主要解决在软件系统中，常常要将一些"现存的对象"放到新的环境中，而新环境要求的接口是现对象不能满足的。
何时使用：
  1、系统需要使用现有的类，而此类的接口不符合系统的需要。
  2、想要建立一个可以重复使用的类，用于与一些彼此之间没有太大关联的一些类，包括一些可能在将来引进的类一起工作，这些源类不一定有一致的接口。
  3、通过接口转换，将一个类插入另一个类系中。（比如老虎和飞禽，现在多了一个飞虎，在不增加实体的需求下，增加一个适配器，在里面包容一个虎对象，实现飞的接口。）

如何解决：继承、依赖（推荐）。
*/
main(List<String> args) {
  AudioPlayer audioPlayer = new AudioPlayer();
  try {
    audioPlayer.play("mp3", "beyond the horizon.mp3");
    audioPlayer.play("mp4", "alone.mp4");
    audioPlayer.play("vlc", "far far away.vlc");
    audioPlayer.play("avi", "mind me.avi");
  } catch (e) {
    if (e is UnimplementedError) {
      print(e.message);
    }
  }
}

//////////////////////////////////////////////////////////////////

///
/// 为媒体播放器和更高级的媒体播放器创建接口
///
abstract class MediaPlayer {
  void play(String audioType, String fileName);
}

abstract class AdvancedMediaPlayer {
  void playVlc(String fileName);
  void playMp4(String fileName);
}

///
/// 创建实现了 AdvancedMediaPlayer 接口的实体类
///
class VlcPlayer implements AdvancedMediaPlayer {
  @override
  void playVlc(String fileName) {
    print("Playing vlc file. Name: $fileName");
  }

  @override
  void playMp4(String fileName) {
    throw UnimplementedError('当前播放器不能播放mp4.');
  }
}

class Mp4Player implements AdvancedMediaPlayer {
  @override
  void playVlc(String fileName) {
    throw UnimplementedError('当前播放器不能播放vlc.');
  }

  @override
  void playMp4(String fileName) {
    print("Playing mp4 file. Name: $fileName");
  }
}

///
/// 创建实现了 MediaPlayer 接口的适配器类
///
class MediaAdapter implements MediaPlayer {
  AdvancedMediaPlayer advancedMusicPlayer;

  MediaAdapter(String audioType) {
    if (audioType.toUpperCase() == "VLC") {
      advancedMusicPlayer = new VlcPlayer();
    } else if (audioType.toUpperCase() == "MP4") {
      advancedMusicPlayer = new Mp4Player();
    }
  }

  @override
  void play(String audioType, String fileName) {
    if (audioType.toUpperCase() == "VLC") {
      advancedMusicPlayer.playVlc(fileName);
    } else if (audioType.toUpperCase() == "MP4") {
      advancedMusicPlayer.playMp4(fileName);
    }
  }
}

///
/// 创建实现了 MediaPlayer 接口的实体类
///
class AudioPlayer implements MediaPlayer {
  MediaAdapter mediaAdapter;

  @override
  void play(String audioType, String fileName) {
    var _type = audioType?.toUpperCase();

    //播放 mp3 音乐文件的内置支持
    if (_type == "MP3") {
      print("Playing mp3 file. Name: $fileName");
    }
    //mediaAdapter 提供了播放其他文件格式的支持
    else if (_type == "VLC" || _type == "MP4") {
      mediaAdapter = new MediaAdapter(audioType);
      mediaAdapter.play(audioType, fileName);
    } else {
      throw UnimplementedError(
          "Invalid media. $audioType format not supported");
    }
  }
}
